﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Neural_Networks.Model
{
    public class Neuron
    {
        private double[] _input, _weight;

        public double Excitation { get; set; }
        public double Output { get; set; }

        public Neuron(double[] x, double[] w, double threshold)
        {
            if (x.Length == w.Length)
            {
                _input = new double[x.Length + 1];
                _weight = new double[w.Length + 1];

                _input[0] = 1;
                _weight[0] = threshold;

                for (int i = 1; i < _input.Length; i++)
                {
                    _input[i] = x[i - 1];
                    _weight[i] = w[i - 1];
                }
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }

        public void SetInputs(double[] x)
        {
            if (x.Length == (_input.Length - 1))
            {
                for (int i = 1; i < _input.Length; i++)
                {
                    _input[i] = x[i - 1];
                }
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }

        public void SetWeights(double[] w)
        {
            if (w.Length == (_weight.Length - 1))
            {
                for (int i = 1; i < _input.Length; i++)
                {
                    _weight[i] = w[i - 1];
                }
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }

        public void SetWeight(uint index, double value)
        {
            if (_weight.Length > index)
            {
                _weight[index + 1] = value;
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }

        public double[] GetInputs()
        {
            return _input;
        }

        public double[] GetWeights()
        {
            return _weight;
        }

        public double GetThreshold()
        {
            return _weight[0];
        }

        public void Calc(Func<double, double> activationFunction)
        {
            Excitation = 0;
            Output = 0;

            for (int i = 0; i < _input.Length; i++)
            {
                Excitation += _weight[i] * _input[i];
            }

            Output = activationFunction(Excitation);
        }
    }
}
